#include "BaseType.h"
#include "Tracer.h"
using namespace std;
using namespace libemb;

/**
 * 状态模式：
 * 1.
 * 2.和策略模式的区别：状态模式服务的对象是相同的，而策略模式服务的对象是不相同的
 * 适用场景：
 * 1.
 * 2.
 **/

enum state_e{
    SLEEP=0,
    WORK
};

class State;
class Context{
DECL_CLASSNAME(Context)
private:
    std::unique_ptr<State> m_sleep;
    std::unique_ptr<State> m_work;
    int m_state;
public:
    Context();
    void setState(int state);
    void doRightThing();
};

class State{
DECL_CLASSNAME(State)
protected:
    Context* m_context;
public:
    State(Context* ctx):m_context(ctx){};
    virtual void handle()=0;
};

class SleepState:public State{
DECL_CLASSNAME(SleepState)
public:
    SleepState(Context* ctx):State(ctx){};
    void handle() override
    {
        TRACE_INFO_CLASS("Sleep State.");
        m_context->setState(WORK);
    }
};

class WorkState:public State{
DECL_CLASSNAME(WorkState)
public:
    WorkState(Context* ctx):State(ctx){};
    void handle() override
    {
        TRACE_INFO_CLASS("Work State.");
        m_context->setState(SLEEP);
    }
};

Context::Context()
{
    m_sleep = std::make_unique<SleepState>(this);
    m_work = std::make_unique<WorkState>(this);
    m_state = SLEEP;
}

void Context::setState(int state)
{
    m_state = state;
}

void Context::doRightThing()
{
    switch(m_state){
    case SLEEP:
        m_sleep->handle();
        break;
    case WORK:
        m_work->handle();
    }
}

int main()
{
    Tracer::getInstance().setLevel(TRACE_LEVEL_DBG);
	Tracer::getInstance().addSink(std::make_shared<STDSink>()).start();

    Context context;
    context.doRightThing();
    context.doRightThing();
    context.doRightThing();
    return RC_OK;
}